﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Telerik.WinControls.UI;
using Umbrella.Whs.Contracts;

namespace Umbrella.Whs.WhsAddin.ConsoleTabControls
{
    internal partial class ConsoleTabControlBase : UserControl
    {
        protected readonly log4net.ILog _log;
        protected readonly SingletonServiceFactory _singletonService = new SingletonServiceFactory();
        protected readonly UmbrellaConsoleTab _tab;

        public string Title
        {
            get; set;
        }

        public Image TitleImage
        {
            get; set;
        }

        public int TabOrder
        {
            get; set;
        }

        public TabItem CreateTabStripItem()
        {
            try
            {
                var i = new TabItem()
                {
                    Text = this.Title ?? GetType().Name,
                    Image = this.TitleImage ?? Properties.Resources.imgDelete16,
                    TextAlignment = ContentAlignment.TopCenter,
                    Tag = this,
                };

                // add this as content
                i.ContentPanel.Controls.Add(this);

                return i;
            }
            catch (Exception x)
            {
                _log.Error("Failed to create tab strip item: " + this.Title, x);

                throw;
            }
        }

        private void SetState(object sender, AddinStateTransitionEventArgs args)
        {
            // log
            if (_log.IsDebugEnabled)
                _log.Debug("Changing state start: " + args.Previous + " to " + args.Next);

            // continue
            try
            {
                this.SuspendLayout();

                // cleanup
                CleanupFlowLayoutPanel();

                // change state
                InitializeState(args.Next);

                this.ResumeLayout();

                // log
                if (_log.IsDebugEnabled)
                    _log.Debug("Changing state done: " + args.Next);
            }
            catch (Exception ex)
            {
                _log.Fatal("Failed to change state from " + args.Previous + " to " + args.Next, ex);

                throw;
            }
        }

        protected virtual void InitializeState(AddinState state)
        {
            // don't do anything
            // to be implemented by child control
        }

        protected void CleanupFlowLayoutPanel()
        {
            foreach (ConsoleControls.ConsoleControlBase c in this.flowLayoutPanel.Controls)
            {
                try
                {
                    c.Dispose();
                }
                catch (Exception ex)
                {
                    _log.Warn("Failed to dispose control", ex);
                }
            }

            this.flowLayoutPanel.Controls.Clear();
        }

        /// <summary>
        /// for designer only
        /// </summary>
        [Obsolete("for designer only")]
        internal ConsoleTabControlBase()
        {
            _log = log4net.LogManager.GetLogger(GetType());

            InitializeComponent();
        }

        public ConsoleTabControlBase(UmbrellaConsoleTab tab)
        {
            if (tab == null)
                throw new ArgumentNullException("tab");

            _tab = tab;
            _log = log4net.LogManager.GetLogger(GetType());

            // initialize
            InitializeComponent();

            // receive state transitions
            AddinStateManager.Instance.OnStateChanging += SetState;
        }

        private void ConsoleTabControlBase_Load(object sender, EventArgs e)
        {
            if (_log.IsDebugEnabled)
                _log.Debug("Loading start");

            try
            {
                // initialize with current state
                InitializeState(AddinStateManager.Instance.State);

                // done
                if (_log.IsDebugEnabled)
                    _log.Debug("Loading done");
            }
            catch (Exception ex)
            {
                _log.Fatal("Loading failed", ex);

                throw;
            }
        }

    }
}
